﻿using AutoMapper;
using B.S.ProcessEgine.API.Applocations.Commands.FormNodes;
using B.S.ProcessEgine.API.Dtos.ResponseDto;
using B.S.ProcessEgine.ErrorCode;
using B.S.ProcessEgine.Infractructure.Interfaces;
using Consul;
using MediatR;
using Microsoft.EntityFrameworkCore;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace B.S.ProcessEgine.API.Applocations.CommandHandlers.FormNodes
{
    public class GetFormNodeCommandHandler : IRequestHandler<GetFormNodeCommand, ApiResult<ApiPaging<FormNodeResponseDto>>>
    {
        private readonly IFormNodeRepository formNode;
        private readonly IMapper mapper;
        private readonly IFormInfoRepository formInfo;
        private readonly IFormTypeRepository formType;

        public GetFormNodeCommandHandler(IFormNodeRepository formNode, IMapper mapper, IFormInfoRepository formInfo, IFormTypeRepository formType)
        {
            this.formNode = formNode;
            this.mapper = mapper;
            this.formInfo = formInfo;
            this.formType = formType;
        }
        public async Task<ApiResult<ApiPaging<FormNodeResponseDto>>> Handle(GetFormNodeCommand request, CancellationToken cancellationToken)
        {
            try
            {
                //获取表单节点列表
                var formNodes = formNode.GetAll().Where(x => 
                (string.IsNullOrEmpty(request.NodeName)||x.NodeName.Contains(request.NodeName)) 
                && (request.FormId == 0 || x.FormId == request.FormId) 
                && !x.IsDel);
                //获取表单列表
                var forms = formInfo.GetAll().Where(x =>
                (request.FormTypeId == 0 || x.TypeId == request.FormTypeId)
                && !x.IsDel);
                //获取表单分类列表
                var formTypes = formType.GetAll().Where(x =>
                (request.FormTypeId == 0 || x.TypeId == request.FormTypeId)
                && !x.IsDel);

                /* //进行连表Linq查询
                 var query = from form in formList
                             join node in nodeList on form.FormId equals node.FormId
                             join type in formTypeList on form.TypeId equals type.TypeId
                             select new FormNodeResponseDto
                             {
                                 FormName = form.FormName,
                                 NextNodeName = node.NextNodeNo,
                                 NodeId = node.NodeId,
                                 NodeName = node.NodeName,
                                 NodeNo = node.NodeNo,
                                 PrevNodeName = node.PrevNodeNo,
                                 TypeName = type.TypeName,
                             };*/

                /*     var query = from nodes in nodeList
                                 join prevnode in nodeList on nodes.PrevNodeNo equals prevnode.NodeNo into prevnodeGroup
                                 from prevnode in prevnodeGroup.DefaultIfEmpty()
                                 join nextnode in nodeList on nodes.NextNodeNo equals nextnode.NodeNo into nextnodeGroup
                                 from nextnode in nextnodeGroup.DefaultIfEmpty()
                                 join form in formList on nodes.FormId equals form.FormId
                                 join type in formTypeList on form.TypeId equals type.TypeId
                                 select new FormNodeResponseDto
                                 {
                                     FormName = form.FormName,
                                     NextNodeName = nextnode.NodeName??string.Empty,
                                     NodeId = nodes.NodeId,
                                     NodeName = nodes.NodeName,
                                     NodeNo = nodes.NodeNo,
                                     PrevNodeName = prevnode.NodeName??string.Empty,
                                     TypeName = type.TypeName,
                                 };*/

                var query = from current in formNodes
                            join prev in formNodes on current.PrevNodeNo equals prev.NodeNo into prevGroup
                            from prev in prevGroup.DefaultIfEmpty()
                            join next in formNodes on current.NextNodeNo equals next.NodeNo into nextGroup
                            from next in nextGroup.DefaultIfEmpty()
                            join form in forms on current.FormId equals form.FormId
                            join type in formTypes on form.TypeId equals type.TypeId
                            select new FormNodeResponseDto
                            {
                                NodeId = current.NodeId,
                                NodeName = current.NodeName,
                                NodeNo = current.NodeNo,
                                FormName = form.FormName,
                                TypeName = type.TypeName,
                                UserName = current.UserName,
                                UserId=current.UserId,
                                PrevNodeName = prev.NodeName ?? string.Empty,
                                NextNodeName = next.NodeName ?? string.Empty
                            };
                


                /*    var query = from type in formTypes
                              join form in forms
                              on type.TypeId equals form.TypeId
                              join current in formNodes 
                              on form.FormId equals current.FormId
                              join prev in formNodes on current.PrevNodeNo equals prev.NodeNo into prevGroup
                              from prev in prevGroup.DefaultIfEmpty()
                              join next in formNodes on current.NextNodeNo equals next.NodeNo into nextGroup
                              from next in nextGroup.DefaultIfEmpty()
                              select new FormNodeResponseDto
                              {
                                  NodeId = current.NodeId,
                                  NodeName = current.NodeName,
                                  NodeNo = current.NodeNo,
                                  FormName = form.FormName,
                                  TypeName = type.TypeName,
                                  PrevNodeName = prev.NodeName ?? string.Empty,
                                  NextNodeName = next.NodeName ?? string.Empty
                              };*/
                //分页
                //分页
                int TotalCount = await query.CountAsync();
                int TotalPage = (int)Math.Ceiling(TotalCount * 1.0 / request.PageSize);

                //数据
                var data = await query.Skip((request.PageIndex - 1) * request.PageSize).Take(request.PageSize).ToListAsync();

                //分页返回的数据
                var result = new ApiPaging<FormNodeResponseDto>(TotalCount, TotalPage, data);

                return ApiResult<ApiPaging<FormNodeResponseDto>>.Success(result,StateCodeEnum.Ok);

            }
            catch (Exception)
            {
                //return await Task.FromResult(ApiResult<ApiPaging<FormNodeResponseDto>>.Fail("查询表单节点失败", StateCodeEnum.Exception));
                throw;
            }
        }
    }
}
